import { EXAM_QUES_OPTION_MAX_LEN, EXAM_QUES_TITLE_MAX_LEN, WordEnum } from '@/common';
import IconFont from '@/components/IconFont';
import {
  ArrowDownOutlined,
  ArrowUpOutlined,
  DeleteOutlined,
  MinusCircleOutlined,
  RightOutlined,
} from '@ant-design/icons';
import { Button, Checkbox, Col, Form, Input, Radio, Row, Space } from 'antd';
import classNames from 'classnames';
import React from 'react';
import OStyle from './index.less';
import type { ExaminationProps } from './interface';

const requireRules = (text: string) => {
  return [{ required: true, whitespace: true, message: text }]; //如果字段仅包含空格则校验不通过，只在 type: 'string' 时生效, 用于checkBox会导致校验不通过, type:number 是会认为值为null
};

const formItemLayout = {
  labelCol: { span: 2 },
  wrapperCol: { span: 18 },
};

const formItemLayoutWithOutLabel = {
  wrapperCol: {
    span: 18,
    offset: 2,
  },
};

const ExaminationItem: React.FC<ExaminationProps> = (props) => {
  const {
    examinationType,
    exaFields,
    exaField,
    exaIndex,
    onAnswerMapSet,
    answerMap,
    title,
    collPanesActiveKeys,
    onSetCollPanesActiveKeys,
    onRemoveExamination,
  } = props;

  const onCollPane = (e: React.MouseEvent, exaIndex: number) => {
    e.stopPropagation();
    const currIndex = collPanesActiveKeys?.findIndex((val) => val === exaIndex);
    if (typeof currIndex === 'number' && currIndex > -1) {
      collPanesActiveKeys?.splice(currIndex, 1);
    } else {
      collPanesActiveKeys?.push(exaIndex);
    }
    onSetCollPanesActiveKeys?.([...(collPanesActiveKeys || [])]);
  };

  return (
    <div className={OStyle.pane_item}>
      {title && (
        <div className={OStyle.item_header}>
          <div
            className={OStyle.header_text}
            onClick={(e) => {
              onCollPane(e, exaIndex);
            }}
          >
            <RightOutlined
              className={classNames(OStyle.text_collapse, {
                [`${OStyle.collapse_rotate}`]: collPanesActiveKeys?.includes(exaIndex),
              })}
            />
            <span className={OStyle.text_text}>{title} </span>
          </div>
          {exaFields.length > 1 && (
            <div className={OStyle.header_operation}>
              <span
                onClick={() => {
                  onRemoveExamination(exaIndex);
                }}
              >
                <DeleteOutlined />
              </span>
            </div>
          )}
        </div>
      )}
      <div
        className={classNames(OStyle.item_content, {
          [`${OStyle.content_hidden}`]: !collPanesActiveKeys?.includes(exaIndex),
        })}
      >
        <div className={OStyle.content_examination_name}>
          {/* 题目 */}
          <Form.Item
            name={[exaField.name, 'content']}
            label="题目"
            rules={requireRules(`请输入【${exaIndex + 1}】题题目`)}
          >
            <Input
              placeholder="请输入"
              showCount
              autoComplete="off"
              style={{ width: 'calc(100% - 140px)' }}
              maxLength={EXAM_QUES_TITLE_MAX_LEN}
            />
          </Form.Item>
        </div>
        {/* 选项 */}
        <div className={OStyle.content_examination_option}>
          <Form.List
            name={[exaField.name, 'selectItemList']}
            rules={[
              {
                validator: async (_, names) => {
                  if (!names || names.length < 2) {
                    return Promise.reject(new Error('至少添加2个选项'));
                  }
                  if (names && names.length > 8) {
                    return Promise.reject(new Error('最多添加8个选项'));
                  }
                },
              },
            ]}
          >
            {(fields, { add, remove, move }, { errors }) => (
              <>
                {fields.map((field, index) => (
                  <Form.Item
                    {...(index === 0 ? formItemLayout : formItemLayoutWithOutLabel)}
                    label={index === 0 ? '选项' : ''}
                    required={true}
                    key={field.key}
                  >
                    <Space.Compact block>
                      <Button size="large">{WordEnum[index]}</Button>
                      <Form.Item
                        {...field}
                        name={[field.name, 'itemValue']}
                        validateTrigger={['onChange', 'onBlur']}
                        rules={requireRules(`请输入第【${index + 1}】项`)}
                        noStyle
                      >
                        <Input placeholder="请输入" autoComplete="off" showCount maxLength={EXAM_QUES_OPTION_MAX_LEN} />
                      </Form.Item>
                      {fields.length > 2 ? (
                        <MinusCircleOutlined
                          className={`${OStyle.option_icon} ${OStyle.icon_delete}`}
                          onClick={() => {
                            // console.log(
                            //   '--remove--field--index--exaIndex--fields--:',
                            //   field,
                            //   index,
                            //   exaIndex,
                            //   fields,
                            // );
                            onAnswerMapSet?.(exaIndex, fields.length, 'remove');
                            remove(field.name);
                          }}
                        />
                      ) : null}
                      {fields.length < 8 && (
                        <IconFont
                          type="icon-tianjia1"
                          className={`${OStyle.option_icon} ${OStyle.icon_add}`}
                          onClick={() => {
                            onAnswerMapSet?.(exaIndex, fields.length, 'add');
                            add(undefined, index + 1);
                          }}
                        />
                      )}
                      {index > 0 && (
                        <ArrowUpOutlined
                          className={`${OStyle.option_icon} ${OStyle.icon_up}`}
                          onClick={() => {
                            move(index, index - 1);
                          }}
                        />
                      )}
                      {index < fields.length - 1 && (
                        <ArrowDownOutlined
                          className={`${OStyle.option_icon} ${OStyle.icon_down}`}
                          onClick={() => {
                            move(index, index + 1);
                          }}
                        />
                      )}
                    </Space.Compact>
                  </Form.Item>
                ))}
                <Row>
                  <Col offset={2}>
                    <div style={{ color: '#ff4d4f' }}>
                      <Form.ErrorList errors={errors} />
                    </div>
                  </Col>
                </Row>
              </>
            )}
          </Form.List>
        </div>
        {/*答案*/}
        <Form.Item
          noStyle
          shouldUpdate={(prevValues, curValues) => {
            // console.log('--prevValues--curValues---', prevValues, curValues);
            //默认 只有formItem name对应的value改变时 formItem才会重新渲染, 这里用作 Checkbox.Group options的更新
            return (
              prevValues.examinationList[exaIndex]?.selectItemList?.length !==
              curValues.examinationList[exaIndex]?.selectItemList?.length
            );
          }}
        >
          {() => (
            <Form.Item
              label="答案"
              name={[exaField.name, 'anwserItemList']}
              validateTrigger={['onChange']}
              required={true}
              rules={
                examinationType === 'mChoiceQue'
                  ? [
                      {
                        validator: async (rule, value) => {
                          if (Array.isArray(value) && value.length > 1) return true;
                          throw new Error(`第【${exaIndex + 1}】题请至少选择两个答案`);
                        },
                      },
                    ]
                  : [
                      {
                        required: true,
                        message: `请选择第【${exaIndex + 1}】题答案`,
                      },
                    ]
              }
            >
              {examinationType === 'mChoiceQue' ? (
                <Checkbox.Group options={answerMap!.get(exaIndex)} />
              ) : (
                <Radio.Group options={answerMap!.get(exaIndex)}></Radio.Group>
              )}
            </Form.Item>
          )}
        </Form.Item>
      </div>
    </div>
  );
};

export default ExaminationItem;
